package com.phz.springcloud.study.service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.phz.springcloud.study.client.CuccScoreClient;
import com.phz.springcloud.study.client.MobileSegmentClient;
import com.phz.springcloud.study.client.WthrcdnClient;
import com.phz.springcloud.study.dao.BalanceDao;
import com.phz.springcloud.study.dao.TransactionDao;
import com.phz.springcloud.study.dao.UserCreditDao;
import com.phz.springcloud.study.entity.Balance;
import com.phz.springcloud.study.entity.Transaction;
import com.phz.springcloud.study.entity.UserCredit;
import com.phz.springcloud.study.util.Sequence;

/**
 * 账号service
 * 
 * @author penghaozhong
 *
 */
@Service
@Transactional(readOnly=true)
public class AccoutService {

	protected static final Logger logger = LoggerFactory.getLogger(AccoutService.class);

	private static final String CURREY = "RMB";

	@Autowired
	private BalanceDao balanceDao;

	@Autowired
	private UserCreditDao userCreditDao;

	@Autowired
	private TransactionDao transactionDao;

	@Autowired
	private MobileSegmentClient mobileSegmentClient;

	@Autowired
	private WthrcdnClient wthrcdnClient;

	@Autowired
	private Sequence sequence;
	
	@Autowired
	private CuccScoreClient cuccScoreClient;

	private static final ObjectMapper mapper = new ObjectMapper();
	
	
	
	/**
	 * 延迟发送短信
	 * @Todo  等待实现
	 * @param phone
	 * @param userName
	 */
	public void saveAccontAndDelaySMS(String phone, String userName){
		// 查询网络数据
		long time = System.currentTimeMillis();

		UserCredit userCredit = new UserCredit();
		userCredit.setPhone(phone);
		userCredit.setUsername(userName);

		String score =  getDataByCuccScoreClient(userCredit);

		logger.info("网络查询服务=========== in {} ms", System.currentTimeMillis() - time);
		
	}
	
	public String saveAccoutInfoGeCuccScore(String phone, String userName){
		// 查询网络数据
		long time = System.currentTimeMillis();

		UserCredit userCredit = new UserCredit();
		userCredit.setPhone(phone);
		userCredit.setUsername(userName);
		
		String score =  getDataByCuccScoreClient(userCredit);

		logger.info("网络查询服务=========== in {} ms", System.currentTimeMillis() - time);
		
		return score;
	}
	
	
	/**
	 * 保存用户账户相关信息
	 * <p>
	 * 1. 保存余额表
	 * <p>
	 * 2. 保存交易表
	 * <p>
	 * 3. 查询用户手机归属地及评分
	 * <p>
	 * 4. 查询用户当前所在的地址和天气
	 * 
	 * @param phone
	 * @param userName
	 * @throws MobileSegmentException 
	 * @throws WthrcdnException 
	 */
	public void saveAccoutInfo(String phone, String userName){

		saveBalanceAndTransaction(phone, userName);

		// 查询网络数据
		long time = System.currentTimeMillis();

		UserCredit userCredit = new UserCredit();
		userCredit.setPhone(phone);
		userCredit.setUsername(userName);

		getDataByMobileSegmentClient(phone, userCredit);

		getDataByWthrcdnClient(userCredit.getPhoneCity(), userCredit);

		logger.debug("网络查询服务=========== in {} ms", System.currentTimeMillis() - time);
	}
	
	
	@Transactional(readOnly=false)
	private void saveBalanceAndTransaction(String phone, String userName) {
		saveBalance(phone, userName);
		saveTransaction(phone, userName);
	}
	

	private void saveBalance(String phone, String userName) {
		Balance balance = new Balance();
		balance.setPhone(phone);
		balance.setUsername(userName);
		balance.setBalance(0);

		balance.setBalanceCurrency(CURREY);
		balance.setCreateTime(new Date());
		balance.setLcsuoBalance(0);
		balance.setLcsuoBalanceCurrency(CURREY);
		balance.setTotalCommissionAmount(0);
		balance.setTotalCommissionCurrency(CURREY);
		balance.setTotalExpenseAmount(0);
		balance.setTotalExpenseCurrency(CURREY);
		balance.setTotalIncomeAmount(0);
		balance.setTotalIncomeCurrency(CURREY);
		balance.setTotalTopupAmount(0);
		balance.setTotalTopupCount(0);
		balance.setTotalTopupCurrency(CURREY);
		balance.setTotalTransactionAmount(0);
		balance.setTotalTransactionCount(0);
		balance.setUpdateTime(new Date());
		balance.setUpdator(userName);

		balanceDao.save(balance);

	}

	private void saveTransaction(String phone, String userName) {
		LocalDateTime dateTime = LocalDateTime.now();

		Transaction transaction = new Transaction();
		transaction.setPhone(phone);
		transaction.setUsername(userName);

		transaction.setAngency(null);
		transaction.setCommissionAmount(0);
		transaction.setCommissionCurrency(CURREY);
		transaction.setCreateTime(new Date());
		transaction.setRelatedId(null);
		transaction.setStatus(1);
		transaction.setTransactionAmount(0);
		transaction.setTransactionCode(
				dateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + "" + sequence.nextId());
		transaction.setTransactionCurrency(CURREY);
		transaction.setTransactionDate(new Date());
		transaction.setTransactionDesc("");
		transaction.setTransactionTime(new Date());
		transaction.setTransactionType(TransactionTypeEnum.COMM.name());
		transaction.setUpdateTime(new Date());
		transaction.setUpdator(userName);

		transactionDao.save(transaction);

	}

	private void saveUserCredit(UserCredit userCredit) {
		userCreditDao.save(userCredit);

	}

	public UserCredit getDataByWthrcdnClient(String city, UserCredit userCredit){

		
		try {
			if(StringUtils.isBlank(city)) {
				compensateWthrcdn("地址位置信息暂无", userCredit);
				return userCredit;
			}
			String data = wthrcdnClient.get(city);
			if (StringUtils.isNotBlank(data)) {
				JsonNode node = mapper.readValue(data, JsonNode.class);
				/**
				 * 接口限流了
				 */
				if(node.path("status").asInt() == 304) {
					compensateWthrcdn("地址位置信息暂无", userCredit);
					return userCredit;
				}
				userCredit.setDate(node.path("data").path("yesterday").path("date").asText());
				userCredit.setHigh(node.path("data").path("yesterday").path("high").asText());
				userCredit.setLow(node.path("data").path("yesterday").path("low").asText());
				userCredit.setType(node.path("data").path("yesterday").path("type").asText());
				
				saveUserCredit(userCredit);
			}
		} catch (Exception e) {
			//throw new WthrcdnException("地址位置信息暂无");
			compensateWthrcdn("地址位置信息暂无", userCredit);
		}
		

		return userCredit;
	}

	public UserCredit getDataByMobileSegmentClient(String phone, UserCredit userCredit)  {
		try {
			String data = mobileSegmentClient.get(phone);
			if (StringUtils.isNotBlank(data)) {
				String iniJsonData = data.substring(data.indexOf("=") + 1, data.length());
				mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);// 设置可用单引号
				mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
				JsonNode node = mapper.readValue(iniJsonData, JsonNode.class);
				userCredit.setPhoneCity(node.get("province").asText());
				userCredit.setPhoneOperator(node.get("catName").asText());

				saveUserCredit(userCredit);
			}
		} catch (Exception e) {
			// throw new MobileSegmentException("手机信息暂无");
			compensateMobileSegment("手机信息暂无", userCredit);
		}

		return userCredit;
	}
	
	public String getDataByCuccScoreClient(UserCredit userCredit)  {
			String data = cuccScoreClient.get();
			if (StringUtils.isNotBlank(data)) {
				userCredit.setPhoneScore(data);
				saveUserCredit(userCredit);
			}
		return data;
	}
	
	
	
	public void compensateMobileSegment(String phoneRemark,UserCredit userCredit) {
		userCredit.setPhoneRemark(phoneRemark);
		userCreditDao.save(userCredit);
	}
	
	public void compensateWthrcdn(String wthrRemark,UserCredit userCredit) {
		userCredit.setWthrRemark(wthrRemark);
		userCreditDao.save(userCredit);
	}

	
	

}
